Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
96.30% covered (success)
96.30%
26 / 27
CRAP
98.48% covered (success)
98.48%
65 / 66
WriteValueCollection
0.00% covered (danger)
0.00%
0 / 1
96.30% covered (success)
96.30%
26 / 27
39
98.48% covered (success)
98.48%
65 / 66
 __construct
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
6 / 6
 fromCollection
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 toReadValueCollection
0.00% covered (danger)
0.00%
0 / 1
2.00
0.00% covered (danger)
0.00%
0 / 1
 toArray
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 first
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 last
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 key
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 next
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 current
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 removeKey
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
10 / 10
 remove
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
5 / 5
 removeByAttributeCode
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
6 / 6
 containsKey
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 contains
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getSame
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getByKey
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
1 / 1
 getByCodes
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getKeys
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getValues
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 count
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 add
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
9 / 9
 isEmpty
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 getIterator
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 clear
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 getAttributeCodes
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 filter
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 generateKey
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
4 / 4
<?php
namespace Akeneo\Pim\Enrichment\Component\Product\Model;
/**
 * Business collection to handle product values.
 *
 * The collection is indexed internally by attribute-channel-locale. The index could be for instance:
 *      description-ecommerce-en_US     for a localizable and scopable attribute
 *      name-<all_channels>-en_US       for a localizable attribute
 *      price-ecommerce-<all_locales>   for a scopable attribute
 *
 * This collection also contains the list of attribute codes used in the collection. This list is indexed by
 * the attribute codes for fast access.
 *
 * @author    Julien Janvier <j.janvier@gmail.com>
 * @copyright 2017 Akeneo SAS (http://www.akeneo.com)
 * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
 */
class WriteValueCollection implements \Countable, \IteratorAggregate
{
    /** @var ValueInterface[] */
    private $values;
    /** @var string[] */
    private $attributeCodes;
    /** @var int[] */
    private $valuesNumberPerAttribute;
    /**
     * @param ValueInterface[] $values
     */
    public function __construct(array $values = [])
    {
        $this->values = [];
        $this->attributeCodes = [];
        $this->valuesNumberPerAttribute = [];
        foreach ($values as $value) {
            $this->add($value);
        }
    }
    /**
     * @param WriteValueCollection $collection
     *
     * @return WriteValueCollection
     */
    public static function fromCollection(WriteValueCollection $collection): WriteValueCollection
    {
        return new static($collection->toArray());
    }
    public function toReadValueCollection(): ReadValueCollection
    {
        return new ReadValueCollection($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function toArray()
    {
        return $this->values;
    }
    /**
     * {@inheritDoc}
     */
    public function first()
    {
        return reset($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function last()
    {
        return end($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function key()
    {
        return key($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function next()
    {
        return next($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function current()
    {
        return current($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function removeKey($key)
    {
        if (!array_key_exists($key, $this->values)) {
            return null;
        }
        $removed = $this->values[$key];
        $attributeCode = $removed->getAttributeCode();
        unset($this->values[$key]);
        $this->valuesNumberPerAttribute[$attributeCode]--;
        if (0 === $this->valuesNumberPerAttribute[$attributeCode]) {
            unset($this->attributeCodes[$attributeCode]);
            unset($this->valuesNumberPerAttribute[$attributeCode]);
        }
        return $removed;
    }
    /**
     * {@inheritDoc}
     */
    public function remove(ValueInterface $value)
    {
        $key = array_search($value, $this->values, true);
        if (false === $key) {
            return false;
        }
        $this->removeKey($key);
        return true;
    }
    /**
     * {@inheritDoc}
     */
    public function removeByAttributeCode(string $attributeCode)
    {
        $removed = false;
        foreach ($this->values as $value) {
            if ($attributeCode === $value->getAttributeCode()) {
                $this->remove($value);
                $removed = true;
            }
        }
        return $removed;
    }
    /**
     * {@inheritDoc}
     */
    public function containsKey($key)
    {
        return array_key_exists($key, $this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function contains(ValueInterface $value)
    {
        return in_array($value, $this->values, true);
    }
    /**
     * {@inheritDoc}
     */
    public function getSame(ValueInterface $value)
    {
        $key = $this->generateKey($value->getAttributeCode(), $value->getScopeCode(), $value->getLocaleCode());
        return $this->getByKey($key);
    }
    /**
     * {@inheritDoc}
     */
    public function getByKey($key)
    {
        return isset($this->values[$key]) ? $this->values[$key] : null;
    }
    /**
     * {@inheritDoc}
     */
    public function getByCodes($attributeCode, $channelCode = null, $localeCode = null)
    {
        $key = $this->generateKey($attributeCode, $channelCode, $localeCode);
        return $this->getByKey($key);
    }
    /**
     * {@inheritDoc}
     */
    public function getKeys()
    {
        return array_keys($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function getValues()
    {
        return array_values($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function count()
    {
        return count($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function add(ValueInterface $value)
    {
        $attributeCode = $value->getAttributeCode();
        $key = $this->generateKey($attributeCode, $value->getScopeCode(), $value->getLocaleCode());
        if (isset($this->values[$key])) {
            return false;
        }
        $this->values[$key] = $value;
        $this->attributeCodes[$attributeCode] = $attributeCode;
        $valuesNumber = $this->valuesNumberPerAttribute[$attributeCode] ?? 0;
        $this->valuesNumberPerAttribute[$attributeCode] = $valuesNumber + 1;
        return true;
    }
    /**
     * {@inheritDoc}
     */
    public function isEmpty()
    {
        return empty($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function getIterator()
    {
        return new \ArrayIterator($this->values);
    }
    /**
     * {@inheritDoc}
     */
    public function clear()
    {
        $this->values = [];
        $this->attributeCodes = [];
    }
    /**
     * {@inheritDoc}
     */
    public function getAttributeCodes()
    {
        return array_values($this->attributeCodes);
    }
    /**
     * {@inheritDoc}
     */
    public function filter(\Closure $filterBy)
    {
        $filteredValues = array_filter($this->values, $filterBy);
        return new self($filteredValues);
    }
    private function generateKey(string $attributeCode, ?string $channelCode, ?string $localeCode): string
    {
        $channelCode = null !== $channelCode ? $channelCode : '<all_channels>';
        $localeCode = null !== $localeCode ? $localeCode : '<all_locales>';
        $key = sprintf('%s-%s-%s', $attributeCode, $channelCode, $localeCode);
        return $key;
    }
}